package cn.ulyer.core.modules.system.rest;


import cn.hutool.core.lang.Assert;
import cn.ulyer.common.annotation.Log;
import cn.ulyer.common.constants.ResultCode;
import cn.ulyer.common.jpa.entity.User;
import cn.ulyer.common.json.jsr.CreateGroup;
import cn.ulyer.common.json.jsr.UpdateGroup;
import cn.ulyer.common.model.PageableVo;
import cn.ulyer.common.security.LoginUser;
import cn.ulyer.common.utils.PageResult;
import cn.ulyer.common.utils.Result;
import cn.ulyer.common.utils.SecurityUtil;
import cn.ulyer.core.modules.system.service.UserService;
import cn.ulyer.core.modules.system.vo.UserVo;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/userRest")
public class UserRest {


    private final String MODULE = "user";

    @Autowired
    private UserService userService;

    @Autowired
    private PasswordEncoder passwordEncoder;


    @GetMapping("/info")
    public Result<LoginUser> info(){
        LoginUser loginUser = SecurityUtil.getUser();
        return Result.ok().data(loginUser);
    }


    /**
     * 分页
     */
    @GetMapping("/page")
    public Result<PageResult<User>> page(PageableVo pageableVo, User tUser){
        PageResult result = userService.page(pageableVo.render(),tUser);
        return Result.ok().data(result);
    }

    @GetMapping("/get")
    public Result<User> detail(@RequestParam Long id){
        return Result.ok().data(userService.getOne(id));
    }

    @Log(action = Log.ActionName.CREATE, module = MODULE)
    @PostMapping("/create")
    public Result<Integer> create(@Validated(CreateGroup.class) @RequestBody UserVo tUser) {
        tUser.setPassword(passwordEncoder.encode(tUser.getPassword()));
        User createUser = new User();
        BeanUtils.copyProperties(tUser, createUser);
        Long uId = userService.createUserWithGroups(createUser, tUser.getGroups());
        return Result.ok(ResultCode.CREATE).data(uId);
    }


    @Log(action = Log.ActionName.UPDATE, module = MODULE)
    @PutMapping("/update")
    public Result update(@Validated(UpdateGroup.class) @RequestBody User tUser) {
        userService.updateById(tUser);
        return Result.ok(ResultCode.UPDATE);
    }

    /**
     * removeById
     *
     */
    @Log(action = Log.ActionName.DELETE,module = MODULE)
    @DeleteMapping("/remove")
    public Result remove(@RequestParam Long id){
        userService.deleteById(id);
        return Result.ok(ResultCode.DELETE);
    }

    @GetMapping("/rolesAndGroups/{uid}")
    public Result<Map<String,List<Integer>>> roleAndGroup(@PathVariable Long uid){
        Map<String,Object> result = userService.findRolesAndGroupsByUid(uid);
        return Result.ok().data(result);
    }

    /**
     *
     * @param json    key roles: integer[]  groups:integer[]
     * @return
     */
    @PostMapping("/updateGroupRole")
    @Log(module = MODULE,action = "修改角色用户组")
    public Result updateGroupRole(@RequestBody JSONObject json) {
        List<Integer> roles = json.getJSONArray("roles").toJavaList(Integer.class);
        List<Integer> groups = json.getJSONArray("groups").toJavaList(Integer.class);
        Long uid = json.getLong("uid");
        Assert.notNull(uid);
        userService.updateGroupRoleByLoginUser(uid, roles, groups);
        return Result.ok();
    }


    /**
     * 更新个人信息
     */
    @PostMapping("/updateSelfInfo")
    @Log(module = MODULE, action = "修改个人信息")
    public Result updateSelfInfo(@Validated(UpdateGroup.class) @RequestBody User user) {
        user.setId(SecurityUtil.getUser().getId());
        user.setExpireTime(null);
        userService.updateById(user);
        return Result.ok();
    }


    @PostMapping("/resetPassword")
    @Log(module = MODULE, action = "修改密码")
    public Result updatePassword(@RequestBody User user) {
        User update = new User();
        update.setId(SecurityUtil.getUser().getId());
        update.setPassword(passwordEncoder.encode(user.getPassword()));
        userService.updateById(update);
        return Result.ok();
    }

}
